package com.tianyadu.mmall.conf;

import com.tianyadu.mmall.entity.SysUser;
import com.tianyadu.mmall.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.social.security.SocialUserDetails;
import org.springframework.social.security.SocialUserDetailsService;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 自定义用户认证信息
 *
 * @author xueyj
 * @date 2019-10-25 15:51
 */
@Slf4j
@Component
public class UserSecurityDetailsService implements UserDetailsService, SocialUserDetailsService {

    @Autowired
    private UserService userService;

    /**
     * 根据用户名，构建用户信息
     *
     * @param userName the username identifying the user whose data is required.
     * @return a fully populated user record (never <code>null</code>)
     * @throws UsernameNotFoundException if the user could not be found or the user has no
     *                                   GrantedAuthority
     * @see org.springframework.security.core.userdetails.UserDetailsService#
     * loadUserByUsername(java.lang.String)
     * <p>
     * Locates the user based on the username. In the actual implementation, the search
     * may possibly be case sensitive, or case insensitive depending on how the
     * implementation instance is configured. In this case, the <code>UserDetails</code>
     * object that comes back may have a username that is of a different case than what
     * was actually requested..
     */
    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        log.info("表单登陆，用户名称：【{}】", userName);
        SysUser sysUser = new SysUser();
        //  用户名
        sysUser.setUsername(userName);
        return buildUser(sysUser);
    }

    /**
     * QQ授权登陆，根据用户id查询用户信息
     *
     * @param userId 用户id
     * @return org.springframework.social.security.SocialUserDetails
     * @author xueyj
     * @date 2019/9/30-1:12
     * @see UserDetailsService#loadUserByUsername(String)
     */
    @Override
    public SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException {
        log.info("社交登陆，用户ID：【{}】", userId);
        SysUser sysUser = new SysUser();
        //  用户openId
        sysUser.setOpenid(userId);
        return buildUser(sysUser);
    }

    /**
     * 构建用户信息
     * <p>
     * Username                    用户名
     * Password                    密码
     * isAccountNonExpired：       用户信息是否过期，true，未过期； false，已过期
     * isAccountNonLocked：        用户账号是否锁定，true，未锁定； false，已锁定
     * isCredentialsNonExpired：   用户密码是否过期，true，未过期； false，已过期
     * isEnabled：                 用户账号是否有效，true，有效；   false，无效
     * Collection<? extends GrantedAuthority> getAuthorities()： 用户权限组;
     *
     * @param sysUser 用户信息
     * @return org.springframework.social.security.SocialUserDetails
     * @author xueyj
     * @date 2019/9/30-1:12
     */
    private SysUser buildUser(SysUser sysUser) {
        List<SysUser> users = userService.findByUserNameOrOpenId(sysUser);
        if (users.size() == 1) {
            return users.get(0);
        } else if (users.size() == 0) {
            throw new UsernameNotFoundException("user " + sysUser.getUsername() + " is not exist!");
        } else {
            throw new UsernameNotFoundException("error!");
        }
    }
}